/*
package com.lai.qq.route.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.byd.dilink.api.common.utils.AesUtils;
import com.byd.dilink.api.common.vo.CodeEnum;
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bucket4j;
import io.github.bucket4j.Refill;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

*/
/**
 * 自定义过滤器进行限流
 * @author xujin
 *//*

@Component
@Slf4j
@RefreshScope
public class RateLimitGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {

    */
/**
     * 单机网关限流用一个ConcurrentHashMap来存储 bucket，
     * 如果是分布式集群限流的话，可以采用 Redis等分布式解决方案
     *//*

    private static final Map<String, Bucket> LOCAL_CACHE = new ConcurrentHashMap<>();

    */
/**
     * 桶的最大容量，即能装载 Token 的最大数量
     *//*

    @Value("${rate.limit.capacity}")
    int capacity = 1;
    */
/**
     * 每次 Token 补充量
     *//*

    @Value("${rate.limit.refillTokens}")
    int refillTokens =1 ;

    */
/**
     * 限制的url
     *//*

    @Value("${rate.limit.urls}")
    String urls;

    */
/**
     *补充 Token 的时间间隔
     *//*

    Duration refillDuration = Duration.ofSeconds(1);

    public RateLimitGatewayFilterFactory() {
    }

    public RateLimitGatewayFilterFactory(int capacity, int refillTokens, Duration refillDuration) {
        this.capacity = capacity;
        this.refillTokens = refillTokens;
        this.refillDuration = refillDuration;
    }

    private Bucket createNewBucket() {
        Refill refill = Refill.of(refillTokens, refillDuration);
        Bandwidth limit = Bandwidth.classic(capacity, refill);
        return Bucket4j.builder().addLimit(limit).build();
    }

    public static Map<String, Bucket> getLocalCache() {
        return LOCAL_CACHE;
    }

    public int getCapacity() {
        return capacity;
    }

    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }

    public int getRefillTokens() {
        return refillTokens;
    }

    public void setRefillTokens(int refillTokens) {
        this.refillTokens = refillTokens;
    }

    public Duration getRefillDuration() {
        return refillDuration;
    }

    public void setRefillDuration(Duration refillDuration) {
        this.refillDuration = refillDuration;
    }

    @Override
    public GatewayFilter apply(Object config) {

        return new RateLimitGatewayFilterFactory.CommonLimitFilterByApi();
    }

    public class CommonLimitFilterByApi implements GatewayFilter, Ordered {


        @SneakyThrows
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
            String api = exchange.getRequest().getPath().value();
            //判断是否有对特定的接口拦截
            if(StringUtils.isNotEmpty(urls)){
                //判断获取请求的url与配置文件里需要限流的url对比，包含就限制，不包含就不限制
                if(!urls.contains(api)){
                    return chain.filter(exchange);
                }
            }
            //判断通过的url走以下是限流逻辑
            Bucket bucket = LOCAL_CACHE.computeIfAbsent(api, k -> createNewBucket());
            log.info("api:{} ,令牌通可用的Token数量:{} " ,api,bucket.getAvailableTokens());
            if (bucket.tryConsume(1)) {
                return chain.filter(exchange);
            } else {
                //当可用的令牌书为0是，进行限流返回429状态码
                //exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
                //return exchange.getResponse().setComplete();
                ServerHttpResponse response = exchange.getResponse();
                JSONObject message = new JSONObject();
                message.put("code", CodeEnum.CODE2.getCode());
                message.put("message", CodeEnum.CODE2.getMessage());
                String res = JSONObject.toJSONString(message);
                //第一层加密
                res = AesUtils.encrypt(res);
                message.put("response",res);
                byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
                DataBuffer buffer = response.bufferFactory().wrap(bits);
                response.setStatusCode(HttpStatus.OK);//设置status为200，不然app无法解析
                //指定编码，否则在浏览器中会中文乱码
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                return response.writeWith(Mono.just(buffer));

            }

        }

        @Override
        public int getOrder() {
            return -2;
        }

    }
}
*/
